#include "cl_programs/common/header.h"

void parse( char *line_record, char *delim, float data_array[], int num)
{
	int i;
    char *pPosition = strtok(line_record, delim);
	float data;

    for (i = 0; i < num; i++)
    {
		data = strtod(pPosition, NULL);
		data_array[i] = data;
		pPosition = strtok('\0', delim);
	}		
}

int main(int argc, char *argv[])
{
	cl_platform_id platform;
	cl_device_id device;
	cl_context context;
	cl_command_queue hCmdQueue;
	cl_mem d_info, d_arr;

	cl_int error;

	char tmp[1024] = {0x0};
	int i, j, k;
	int current_row = -2;
	int row_count = 0;
	int M, NUM_ROWS;
	int numTabs = 0;
	int firstTime = 1;
	int size_arr, mem_size_arr, size_info, mem_size_info;

	FILE *in = fopen(argv[1],"r");         
	FILE *out = fopen("test_out.txt","w"); 

	if(in == NULL)
	{
		perror("File open error");
		exit(EXIT_FAILURE);
	}

	while(fgets(tmp, sizeof(tmp), in) != 0)
	{
		char ch;
		int i1 = 0;
		ch = tmp[0];
		while(ch != '\0' && firstTime)
		{
			ch = tmp[i1];
			if(ch == '\t')
			{
				numTabs++;
			}
			i1++;
		}
		row_count++;
		firstTime = 0;
	}

	M = numTabs + 1 - 3;
	NUM_ROWS = row_count - 2;

	size_arr = M * NUM_ROWS;
	mem_size_arr = sizeof(float) * size_arr;
	float *h_arr = (float*)malloc(mem_size_arr);

	fclose(in);
	in = fopen(argv[1], "r");

	float *blank = (float*)malloc(sizeof(float) * M);

	while(fgets(tmp, sizeof(tmp), in) != 0)
	{
		char *realPtr;
		int numTabsSkipped;
		if( current_row < 0)
		{
			current_row++;
			continue;
		}
		realPtr = tmp;
		numTabsSkipped = 0;
		while(numTabsSkipped < 3)
		{
			realPtr++;
			if(*realPtr == '\t')
			{
				numTabsSkipped++;
			}
		}
		realPtr++;
		parse(realPtr,"\t", blank, M);  
		for(i = 0; i < M; i++)
		{
			h_arr[current_row * M + i] = blank[i];
		}
		current_row++;
	}

	fclose(in);

	size_info = NUM_ROWS * NUM_ROWS;
	mem_size_info = sizeof(float) * size_info;
	float *h_info = (float*)malloc(mem_size_info);

	float *answer = (float*)malloc(sizeof(float) * NUM_ROWS * NUM_ROWS);


	error = oclGetPlatformID(&platform);
	oclCheckError(error, CL_SUCCESS);

	error = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
	oclCheckError(error, CL_SUCCESS);

	context = clCreateContext (0, 1, &device, NULL, NULL, &error);
	oclCheckError(error, CL_SUCCESS);

	hCmdQueue = clCreateCommandQueue(context, device, 0, &error);
	oclCheckError(error, CL_SUCCESS);

	d_arr = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, mem_size_arr, h_arr, &error);
	assert( error == CL_SUCCESS);

	/*d_pdfxy = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_pdfxy, &error);
	assert( error == CL_SUCCESS);

	d_pdfx = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_pdfx, &error);
	assert( error == CL_SUCCESS);

	d_pdfy = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_pdfy, &error);
	assert( error == CL_SUCCESS);

	d_z = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_z, &error);
	assert( error == CL_SUCCESS);

	d_norm = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_norm, &error);
	assert( error == CL_SUCCESS);

	d_xz = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_xz, &error);
	assert( error == CL_SUCCESS);

	d_yz = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_yz, &error);
	assert( error == CL_SUCCESS);

	d_normxy = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, array_size, h_normxy, &error);
	assert( error == CL_SUCCESS);*/

	d_info = clCreateBuffer(context, CL_MEM_READ_WRITE, mem_size_info, NULL, &error);
	assert( error == CL_SUCCESS);
		
	initMutInfoGPU(context, device);
	MutInfoGPU(hCmdQueue, d_info, d_arr, M, NUM_ROWS);

	error = clEnqueueReadBuffer(hCmdQueue, d_info, CL_TRUE, 0, mem_size_info, answer, 0, NULL, NULL);
	assert( error == CL_SUCCESS);

	 

	for(j = 0; j < NUM_ROWS; j++)
	{
		for(k = 0; k < NUM_ROWS; k++)
		{
			fprintf(out, "Row%d vs. Row%d %f  \t",j , k, answer[j * NUM_ROWS + k]);
		}
		fprintf(out, "\n");
	}

	closeMutInfoGPU();
	error = clReleaseMemObject(d_info);
	error |= clReleaseMemObject(d_arr);
	error |= clReleaseCommandQueue(hCmdQueue);
	error |= clReleaseContext(context);
	assert( error == CL_SUCCESS);

	free(h_info);
	free(h_arr);
	free(answer);
	
	fclose(out);
	//shrExit(argc, argv);
}
